package org.wheel.plugins.starter.jdbc.pool.util;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.wheel.plugins.toolkit.jsqlparse.helper.ParamValueConvert;
import org.wheel.plugins.toolkit.sql.entity.BeanMeta;
import org.wheel.plugins.toolkit.util.ReflectUtil;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 实体操作工具类
 */
public class EntityOperationUtil {

    // 直接使用 LogFactory 创建日志对象，Hutool 会自动检测项目中的日志框架（优先级：Slf4j > Log4j > Logback > JDK Logging）
    private static final Log log = LogFactory.get();
	/**
	 * New data is inserted into the creator, creation time, update person, update time, otherwise only modify the change person, change time
	 * 新数据则插入创建人ID，创建时间，更新人ID，更新时间，否则只修改更改人ID，更改时间
	 * @param source  userId
	 * @throws Exception
	 * @author liukang
	 */
	public static void perInserOrUpdate(Object source, String userId) {
        if(source==null){
            return;
        }
        BeanMeta beanMeta = BeanMeta.of(ClassUtil.getClass(source));
        if(beanMeta==null){
            return;
        }
		try {
            String keyField = beanMeta.getKeyField().getFieldName();
			//新数据则需要更新创建人，创建时间
			if(!ReflectUtil.judgmentValue(source, keyField)) {
                if(beanMeta.hasCreateBy()) {
                    ReflectUtil.perInserOrUpdate(source, beanMeta.getCreateByField().getFieldName(), userId);
                }
                if(beanMeta.hasCreateTime()) {
                    ReflectUtil.perInserOrUpdate(source, beanMeta.getCreateTimeField().getFieldName(), getDateValue(beanMeta.getCreateTimeField().getFieldType()));
                }
                if(beanMeta.hasLogicDelete()) {
                    ReflectUtil.perInserOrUpdate(source, beanMeta.getLogicDeleteField().getFieldName(), "0");
                }
			}
            if(beanMeta.hasUpdateBy()) {
                ReflectUtil.perInserOrUpdate(source, beanMeta.getUpdateByField().getFieldName(), userId);
            }
            if(beanMeta.hasUpdateTime()) {
                ReflectUtil.perInserOrUpdate(source, beanMeta.getUpdateTimeField().getFieldName(), getDateValue(beanMeta.getUpdateTimeField().getFieldType()));
            }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * New data is inserted into the creator, creation time, update person, update time
	 * 新增数据时，在保存进入数据库前，执行此方法，填入创建人ID，创建时间，更新人ID，更新时间 信息
	 * @param source
	 * @param userId
	 */
	public static void perInsert(Object source, String userId) {
		try {
            if(source==null){
                return;
            }
            BeanMeta beanMeta = BeanMeta.of(ClassUtil.getClass(source));
            if(beanMeta==null){
                return;
            }
            if(beanMeta.hasLogicDelete()) {
			    ReflectUtil.perInserOrUpdate(source, beanMeta.getLogicDeleteField().getFieldName(), ParamValueConvert.convertValue(beanMeta.getLogicDeleteField().getFieldType(), "0"));
            }
            if(beanMeta.hasCreateBy()) {
			    ReflectUtil.perInserOrUpdate(source, beanMeta.getCreateByField().getFieldName(), userId);
            }
            if(beanMeta.hasCreateTime()) {
			    ReflectUtil.perInserOrUpdate(source, beanMeta.getCreateTimeField().getFieldName(),
                        getDateValue(beanMeta.getCreateTimeField().getFieldType()));
            }
            if(beanMeta.hasUpdateBy()) {
			    ReflectUtil.perInserOrUpdate(source, beanMeta.getUpdateByField().getFieldName(), userId);
            }
            if(beanMeta.hasUpdateTime()) {
			    ReflectUtil.perInserOrUpdate(source, beanMeta.getUpdateTimeField().getFieldName(),
                        getDateValue(beanMeta.getUpdateTimeField().getFieldType()));
            }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 *  only modify the change person, change time
	 *  更新数据时，在保存进入数据库前，执行此方法，填入更新人ID，更新时间 信息
	 * @param source
	 * @param userId
	 * @author liukang
	 */
	public static void perUpdate(Object source, String userId) {
        if(source==null){
            return;
        }
        BeanMeta beanMeta = BeanMeta.of(ClassUtil.getClass(source));
        if(beanMeta==null){
            return;
        }
		try {
            if(beanMeta.hasUpdateBy()) {
			    ReflectUtil.perInserOrUpdate(source, beanMeta.getUpdateByField().getFieldName(), userId);
            }
            if(beanMeta.hasUpdateTime()) {
			    ReflectUtil.perInserOrUpdate(source, beanMeta.getUpdateTimeField().getFieldName(),
                        getDateValue(beanMeta.getUpdateTimeField().getFieldType()));
            }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

    /**
     * 获取当前时间
     * @param dateFieldType 时间字段类型
     * @return 时间对象
     */
    public static Object getDateValue(Class<?> dateFieldType){
        if(dateFieldType==null){
            return null;
        }
        if(dateFieldType.equals(LocalDateTime.class)){
            return LocalDateTime.now();
        }else if (dateFieldType.equals(java.util.Date.class)){
            return new java.util.Date();
        } else if (dateFieldType.equals(LocalDate.class)) {
            return LocalDate.now();
        }
        log.warn("dateFieldType is not support");
        return null;
    }
}
